General Info | Template Language | WCTL Commands | WebX/Chat | WebX/Pro |
Release Notes | Standard Templates | URL Codes | WebX/Multi | FastCGI, NSAPI, ISAPI |
Visit the Web Crossing Conference to find a wealth of WebX info and a community of WebX experts on the Web!
Using the Web Crossing Template Language
Location | path.xxxx | path$xxxx |
---|---|---|
Folder 1 | "abc" | "abc" |
Folder 1/Folder 2 | "" | "abc" (from Folder 1) |
Folder 1/Folder 2/Discuss | "def" | "def" |
WCTL directives are identified by two percent signs, the command, and then two more percent signs, i.e. %%...%%. If you enter
Hello <b>%% username %%!</b>
the actual display seen by the user will be something like
A template is the HTML text for an entire page or portion of a page to be served by Web Crosing. You can enter templates in the various sysop control panels to easily customize much of the apperance of your site, such as the banner and footer for each page.
In addition to the sysop control panel, you can use the webx.tpl file to customize your entire site. The webx.tpl file is a collection of templates and macros to be used by Web Crossing. You can specify template macros for any of the user interface pages served by Web Crossing. You can also define your own templates to create your own unique pages, or define your own templates as a convenience when the same HTML and WCTL directives are used in more than one place.
If there is no whole-page template, then Web Crossing will construct the page from smaller pieces. These pieces are specified through the sysop control panel or through templates in your webx.tpl and webxextn.tpl files. The template files are checked first, and if a template is defined therein it is used; otherwise, the sysop control panel setting is used.
When Web Crossing builds a response page, it starts with the sysop-defined banner, adds items appropriate for the response, and concludes with the sysop-defined footer. You can do extensive customization of each page through the various sysop control panels. You can edit default HTML text, and you can use WCTL directives as appropriate.
The steps to customize whole pages are as follows.
%% macro login %% ...contents of login template... %% endmacro %%
All of the templates used to layout a folder page are optional. They may be specified through the sysop control panel, through the webx.tpl file, or on a folder-by-folder or discussion-by-discussion basis.
For more detail on the folder templates, see the Folder template sections.
All of the templates used to layout a discussion page are optional. They may be specified through the sysop control panel, through the webx.tpl file, or on a folder-by-folder or discussion-by-discussion basis. (If specified in a folder, then all discussions in that folder will share the same templates.)
For more detail on discussion templates, see the Discussion template sections.
For your convenience, you can also collect changes to these additional fields through the built-in registration and user-preferences forms. To customize the register and editPreferences template forms, follow the steps above in the Customizing whole pages section to move these templates into your webx.tpl file.
To add your own user information fields, edit the templates in your webx.tpl file. Use <input name=user followed by a dot and your variable name, such as <input name=user.city. Then, when Web Crossing processes the form, it will set this user value for you from the form input.
For example, to have users enter their phone number at registration time, add the following to the register template:
Your phone number: <input name=user.phone type=text size=30 max=50>
Note that "user." is required. Web Crossing specifically checks for variables starting with "user." for values to store into your variables. In this example, once the phone number has been added to the user record, you can access it with user.phone or author.phone.
To continue this example, you can allow users to edit their phone number in their user-preferences form, by adding the following to the editPreferences template:
Your phone number: <input name=user.phone type=text size=30 max=50 value="%% user.phone %%">
Note that %% user.phone %% will show the current phone number for editing.
To display a user's phone number in your site's personal information form, use author.phone in the userInfo template, such as
%% if author.phone %% Phone number: %% author.phone %%<p>%% endif %%
This will display the phone number if available.
Title: <b>%% pathTitle %%</b>might display as
WCTL expressions are not case-sensitive, so "username" is the same as "USERNAME" or "UserName". You may place blanks inside the %% marks for readability. For example,
You may use tabs to indent conditional sections. All of these leading tabs are automatically removed from the output.
In order to make it WCTL easier to read, the newline following a directive is also removed. For example,
<a href="xxx">%% nop %% <img src=yyy></a>would be output as
<a href="xxx"><img src=xxxx></a>
All variables evaluate to either a text string, an integer number, or to a boolean (true/false) value. For example, %% username %% evaluates to the name of the current user, while %% if userIsSysop %% takes the true branch if the current user is the sysop.
Text variables may evaluate to an empty string, that is, a string with no characters. For example, %% user2ndLine %%, the second line of user information, will be empty until a user fills it in.
In an if test, text strings are true when they have any characters, and false when they are empty. For example,
%% if user2ndLine %% <p>Other information: %% user2ndLine %% %% endif %%
will only insert <p>Other information:... when there is a second line.
Numeric values are considered to be true if they are non-zero, or false if they are zero.
String and integer values are automatically converted as required. A non-numeric string is converted to the integer value 0. For example,
Boolean variables are 0 for false and 1 for true. You can use boolean variables to control the text that is placed into the page returned to the user. For example,
%% if userIsSubscribed %% subscribed %% else %% not subscribed %% endif %%will add subscribed or not subscribed to the page.
Operator precedence, from highest to lowest (highest are done first):
Operators | Use |
---|---|
+ - | unary plus and minus |
* / % & | times, divide, modulus, string-catenate operators |
+ - | plus or minus operators |
< <= > >= | less-than, less-than-or-equal, greater-than, greater-than-or-equal comparison |
== != | equal and not-equal comparison |
&& | logical AND |
|| | logical OR |
() | in an expression |
Numeric constants can be a number, such as -5, 0, or 1429. They can also be the integer value of a character, such as 'a' or 'Z'.
String constants are in double-quotes, such as "abc". The empty string is "". To put a double-quote character in a string, repeat it, such as """" (which evaluates to a string of one double quote).
Variable Usage | Scope | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
varName | Local variable. Once you set a local variable it
can be referenced from any template in the current execution,
not just the one that set it.
Local variables are always cleared before evaluating a new template or
sysop template.
To keep a value around from page to page, use a user-record variable,
a current-location path variable, or a global site variable.
For example,
| ||||||||||||
user.varName | User variable.
User variables are stored in the database as an additional field in the user record,
so they are saved with the database and are available as a permanent part
of the user's record.
For example,
In the user registration and editPreferences templates, you can use these variables as the name of an input field, and Web Crossing will automatically set them for you when it processes the form. For example, adding
| ||||||||||||
author.varName | Author variable. Same as a user variable, but in the
user-record for the author of the current location.
For example, in a message display or personal information form,
| ||||||||||||
path.varName | Path or location variable, defining an additional
field for the current location.
Path variables are stored in the database as an additional field for
any folder, discussion, message, link, or chat room, and are saved with the database.
For example,
Sometimes you want to find a value from either the current location or, if not defined there, then from the closest parent that defines it. This allows you to use "inheritance" by folder and discussion hierarchy. To find the closest definition of a value, use path$varname. For example,
| ||||||||||||
site.varName | Global site variable, defining an
additional field for the global site information. Site variables are saved with the database.
For example,
|
The built-in location and pathXxx variables a reference the current location in the Web Crossing forums. You can change the current location with setPath(...). Values for custom "path" variables like path.customFooter must be assigned to each folder/discussion/message object. They do not inherit values from the same variables in their containing objects, but you can use path$customFooter to reference either the value from the current location, or from the closest parent if not defined in the current location.
%% if 1 %% TRUE %% else %% FALSE %% endif %%
will display as
TRUE
The conditional commands are if, else, endif, else if, elsif, and elseif. (The various "else if" options are all equivalent.)
You can use any built-in variable or expression in an if test. Empty strings evaluate as false, and non-empty strings as true. You can also use
if awayhours > nnnto check for the last login having been more than "nnn" hours ago, or
if lastLogin < mm/dd/yyyy.hh:mm:ssto check whether the prior login was before a particular date.
%% set posts user.userposts(5) %% %% set post posts.split %% %% while post %% %% setPath(post) %% %% pathDate %%<br> %% set post posts.split %% %% endwhile %%This while loop iterates over a list of up to 5 most recent posts by the current user, and displays the date for each post. userposts(5) returns the 5 most recent posts as location unique IDs. posts.split returns the first blank-delimited location, and sets posts to the remaining locations. setPath(post) sets the current location, so pathDate can display its date.
In a while loop, you can use %% break %% to exit the loop, and %% continue %% to go to the top of the loop. For example, the following rather contrived loop will display all the even numbers less than 100:
%% set start -1 %% %% while 1 %% %% set start start+1 %% %% if start >= 100 %% %% break %% %% endif %% %% if start % 2 == 1 %% %% continue %% %% endif %% %% start %%- %% endwhile %%
In order to prevent infinite loops, Web Crossing limits the maxiumum number of while-loop iterations per page. The default setting is 1000, and can be changed through the sysop General Settings panel.
is a macro that evaluates to something like Hello World on Feb 26, 1998.
The webx.tpl file allows you to define macros for a variety of uses.
When Web Crossing constructs a reponse to a URL, it first checks the webx.tpl and webxextn.tpl files for a template macro for the response. The template macro for a specific request is located by name; see the Standard Templates document for a listing. The standard.tpl file contains a complete set of default templates that you can easily customize for your site.
%% macro greetingNews %% Hello %% userName %%. %% endmacro %%will set the sysop Greeting template to Hello %% userName %%.
Before Web Crossing gets a value from the sysop control panel, it checks to see if this value is defined in the webx.tpl or webxextn.tpl files. (This allows you to define all of the sysop settings together in webx.tpl.) Again, see the Standard Templates document for a listing.
Note: after you make changes to the webx.tpl file, you must click on the "Reset file cache for HTML files and webx.tpl templates" link in the sysop control panel, in order for Web Crossing to pick up your changes.
%% use greetingNews %%would insert the current greeting template into the output text.
The template you call can be either built-in or one you have defined.
There is a maximum depth of 50 calls, so that infinite loops (e.g. a calls b, b calls a) don't run forever.
To define your own pages, use the following steps:
%% macro yourMacro_ %% ...HTML and template expressions for your page... %% endmacro %%
It is good practice to put an underscore in your template name, because Web Crossing built-in templates will never use this character.
If you need a user to be logged in before a full-page template macro should be used, you can insert the following check at the start of the macro:
%% if userIsUnknown %% %% return %% %% endif %%
When a full-page template macro returns all white space, Web Crossing will display a login page. On a successful login, the original template macro will be reexecuted with the same parameters.
You process a form by linking the submit button to a Web Crossing template. For example,
where myFormProcess is the name of your form-processing template. Web Crossing will replace %% urlBase %% with the base URL for your Web Crossing server, %% certificate %% with the user's current access certificate, and %% location %% with the user's current location in the Web Crossing conference. (These are all standard components of a Web Crossing URL).
You access form variables by using %% form.fieldname %%. For example,
The complete templates could be something like:
If you are running with FastCGI, all of the environment variables are avaiable. Through the standard CGI, you can only access a subset of the variables.
To get a list of variables in your environment, use the showEnvir template from standard.tpl. You first need to move the showEnvir template into your webx.tpl file, as described in the Customizing Whole Pages section. Then use a URL to access Web Crossing as
To send a cookie along with the response to the client, use something like
To get the value of a cookie that is part of the current request, use
Note that cookie values cannot include white space or semicolons. If you are building a cookie value dynamically, it is recommended that you URL quote it, which will remove all these values. For example, set the cookie to a value with
The set-cookie syntax is as follows.
Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
The date string is formatted as:
Wdy, DD-Mon-YYYY HH:MM:SS GMT
expires is an optional attribute. If not specified, the cookie will expire when the user's session ends.
Note: There is a bug in Netscape Navigator version 1.1 and earlier. Only cookies whose path attribute is set explicitly to "/" will be properly saved between sessions if they have an expires attribute.
Only hosts within the specified domain can set a cookie for a domain and domains must have at least two (2) or three (3) periods in them to prevent domains of the form: ".com", ".edu", and "va.us". Any domain that fails within one of the seven special top level domains listed below only require two periods. Any other domain requires at least three. The seven special top level domains are: "COM", "EDU", "NET", "ORG", "GOV", "MIL", and "INT".
The default value of domain is the host name of the server which generated the cookie response.
Because of various browser bugs, you must specify the path.
If secure is not specified, a cookie is considered safe to be sent in the clear over unsecured channels.
To find the correct template, Web Crossing first checks the templates assigned to the current folder. If not found, then the parent folder is checked, and so on to the top-level. If still not found, then the top-level of the webx.tpl and webxextn.tpl files are checked. If still not found, then the sysop panel templates are checked.
To override the templates for a folder, use the following steps:
%% macro yourFolderMacro %% %% macro folderListBefore %% ...your HTML text to insert before the folder's item list... %% endmacro %% %% macro folderListItem %% ...your HTML text to customize each folder item... %% endmacro %% %% macro folderListAfter %% ...your HTML text to insert after the folder's item list... %% endmacro %% %% endmacro %%
where filename is the file to include. You must use this syntax exactly: spaces, capitalization, and all.
Whenever a WCTL page evaluates to text starting with "HTTP/", that page is returned as is, without adding the normal HTTP response heading. For example, the following template forwards the request ...WebX?forward@@ to a discussion.
%% macro forward %% HTTP/1.0 302 Redirect%% crlf %% Location: http%% if siteIsSecure %%s%% endif %%://%%siteHost%% %%urlBase%%14@%%alwaysCertificate%%@%%location%%%% crlf %%%% crlf %% %% endmacro %%A carriage-return/linefeed is added to the end of each line by the built-in crlf variable. Because Web Crossing strips trailing newlines following an expression (e.g. following %% crlf %%), you can write the response on multiple lines for readability, without having extra newlines inserted into the result.
HTTP/1.0 302 Redirect is the standard first line for a response from a Web server to the user's Web browser. This one has a response code of 302, which asks the browser to temporarily forward the original URL to a new location.
Location:... is the fully-qualified URL to which to forward.
Note that the response must end with a final blank line.
HTML documents include formatting and other directives. For example,
<b>Sample text</b>will display as
Sample textin the user's Web browser.
SGML quoting converts all of the HTML special characters (<, >, etc) to their quoted format (<, >, etc). The result is a text string that displays exactly as the original text. If you "SGML quote" the sample text in an HTML document to
<b>Sample text</b>then it will display exactly as the original.
URL quoting takes the actual pathname and replaces special URL characters with a percent sign and 2 hexadecimal digits (e.g. blanks are replaced with %20). For example, in a URL,
My pathnamebecomes
My%20pathname
In WCTL, most values are automatically quoted. For example, %% userName %% is SGML quoted, and %% parentUrl %% is URL quoted.
You can explicitly control SGML and URL quoting in Web Crossing. For example, %% userName.fromSGML %% is the original user name without SGML quotes. See the string functions in the WCTL Built-in Variables document for a list of available conversions.
For example, suppose you need to get the e-mail address of a user from an external database. You can run a script to obtain this from the external database, and then embed this information into the current page. You might use
The server-side include directives for Web Crossing are:
exec( commandLine ) | Run a program with the specified command line, and return the output from the program. For example, exec( "myProgram" ). |
cgi( commandLine ) | Run a program with the specified command line, and also set all the environment variables from the current CGI request. For example, cgi( "myCgiProgram" ). (See the section on CGI Environment Variables above.) |
file( pathname ) | Read the contents of the specified file, such as file( "prefix" ). |
scriptError | The error message for the last exec or cgi program, or the empty string if no error.. |
fileError | The error message for the last file include, or the empty string if no error.. |
The results from exec, cgi, or file can be multiple lines long, they are not restricted in any way. Also, the results of exec, cgi, or file can also be stored into a variable for use as desired. For example,
The first line of the message is the list of users, and the remainder of the message is a normal e-mail message including the full heading. For example,
Filter macros can examine form fields and take appropriate action: return a complete page to send to the user, forward the user to a different URL, construct an error message, return a user ID for the registered user, or return a blank page for normal processing.
For example, the following macro will check a registration post for objectionable words, and return an error message to be displayed for the user to correct the problem:
Filter macro | Usage |
---|---|
authenticateFilter | If present, called after the normal WebX authentication,
before processing the request. The user variable is set to the
user as authenticated by Web Crossing.
The original request including the certificate is available through
envir.query_string, and any cookies are available through
envirCookie( "cookieName" ).
This macro outputs one of the following:
|
loginFilter | |
If present, called after the normal WebX login,
before processing the login actionPath. The user variable is set to the
user as authenticated by Web Crossing.
The original request including the certificate is available through
envir.query_string, and any cookies are available through
envirCookie( "cookieName" ).
This macro outputs one of the following:
| |
loginFailureFilter | If present, called after the normal WebX login fails. If the user exists but
the password was wrong, then the user variable is set.
The original request including the certificate is available through
envir.query_string, any cookies are available through
envirCookie( "cookieName" ), and the login form fields are available through
form.username and form.password.
This macro outputs one of the following:
|
registerProcessFilter | If present, this macro is called before processing a registration form.
It returns one of the following:
|
registerFailureFilter | |
If present, this macro is called after processing a registration form,
when the registration request had some error.
It returns one of the following:
| |
httpBasicNewFilter | If present, this macro is called when HTTP basic authentication is turned on,
and the incoming user is not in the Web Crossing user directory.
It returns one of the following:
|
To just link to a folder or discussion, you can go to that location in your Web browser, copy the URL of the location, and delete the text between the at (@) signs. For example,
http://webcrossing.com/webx?14@0.ag4d3fde^0@/Test
would be edited to
http://webcrossing.com/webx?14@@/Test
for use in a link you are building.
http://your_site/<access path>[?<command>[L]@<certificate>@<parameters>]
where [...] is an optional component.
<access path> | is the name of the CGI script or other interface between Web Crossing and your Web server. |
<command> | is either a command code or a template you have defined. |
L | if the command code is followed by L, the user will be asked to login. (This option is not available for pages you have defined.) |
<certificate> | is used to identify the current user, provides an optional tag used by you to configure the user interface for a particular access path, and includes a sequence number to force a user's client to fetch new information instead of using old cached material. |
<parameters> | is additional information required for a command.
This is almost always the location in the conference to which a command applies. The location may be a folder, a discussion, or a message in a discussion. |
If the command is omitted entirely, then Web Crossing uses the default command you entered in your Banner, footer, background, and top-level page appearance panel, or to the top-level folder.
Commands typically apply to a location.
Some login and registration messages need to first login the user, then perform the command. They take an actionPath as a parameter. The action path is the command code, an at (@) sign, and the parameters for that command. For example, the action path to show a particular folder might be 14@/Books.
Some commands process a form submitted by POST command. The contents of the form is sent as a string where each input item starts with a name, followed by '=', followed by a value, followed by '&'. For example, the post data for Process Login (23) includes the user's name and password, e.g., username=Adam Smith&password=xx&.
The set of input items for a command is defined by the corresponding form from Web Crossing. On Unix systems, you may use 'webx-go -stdio' to retrieve the form. For example get 15@@ shows the form that invokes Process Login. On Mac and Windows NT, use Save As Source in your browser.
See the Command Codes document for a complete listing of available codes.
Certificate syntax is:
[<slot>.][<userkey>][-<tag>][^<seqno>]
where [...] is an optional component.
<slot> | is a number from 0 to 999, and is the slot assigned to this certificate. |
<userkey> | is omitted for an unknown user, or is 8 random characters for a registered or guest user. This random user key is used to identify the user, and authorizes his/her access. The userkey is assigned at the time the user logs in or registers. The userkey is valid for a timeout period, usually 30 minutes, and expires automatically if the user doesn't issue another request during the timeout period. |
<tag> | is an optional component that may be used in templates to keep track of a user's options. The meaning of a tag is defined by the site designer. |
<seqno> | is a number starting with 1 that is incremented for each response, and is used to make the client side fetch new pages instead of showing an old cached page. |
For example, the following table shows some possible certificates:
Certificate | Usage |
---|---|
0.abcxyzaa^1 | A typical certificate for a logged-in user. |
0.abcxyzaa-TEXT^2 | A typical certificate for a logged-in user, with a tag of TEXT. |
An empty certificate for first-time entry | |
-TEXT | A tag-only certificate for first-time entry. |
^243 | A typical unknown user with guest access. The sequence number is used to force the user's browser to fetch current pages. |
To customize your site based on the user's tag, use the %% if certificateIs tag %% variable.
As a user navigates through the conference, the original entry tag is propagated automatically. You can switch the certificate to a new tag through the certificate variable.
Folder pathnames may use folder titles, such as /Books, or the unique ID of the folder, such as .aef345. Note that long titles may cause errors in your HTTP server.
Discussion pathnames may be either a folder pathname and discussion ID number, such as /Books/3, or the unique ID of the discussion, such as .aef34a. (Discussion IDs are assigned starting from 1 and are not reused if a discussion is deleted.)
Individual messages are located by their discussion pathname and message ID. For example, /Books3/22 or .aef372/22. (Message numbers are assigned starting from 0 and are not reused if a message is deleted.)
The location pathname must use URL quotes. For example, blanks must be replaced by %20, as in /Books%20in%20Russian/3.
<b><a href="%%siteUrl%%">The Best Place</a></b><br><b>Forum: <a href="%% parentUrl 1 %%">%% parentTitle 1 %%</a></b>%% if pathIsFolder %% <p>%% else %% <br><b>Topic: <href="%% parentUrl 2 %%">%% parentTitle 2 %%</a></b><p>>%% endif %%
This might display as:
<a href="%% pathUrl %%"> %% pathIcon border=0 align=bottom%% <b>%%nop%% %% pathTitle %% </b>%%nop%% %% if pathHasMessages %% <font size=2>(%%nop%% %% pathMessageCount %% %% if pathHasOneMessage %% message%%nop%% %% else %% messages%%nop%% %% endif %% %% if pathHasNewMessages %% ,%%nop%% %% pathNewMessageCount %% new %%nop%% %% endif %% )</font>%%nop%% %% endif %% </a><br>
Note how this template is made more readable by using %%nop%% to suppress newlines in the output. (This works because Web Crossing removes newlines that immediately follow a variable. The indents in this example should be replaced by tabs if you copy this for your use (again, because Web Crossing strips leading tabs to help make the template more readable).
You can see some of the various substitution values by going to the Folder appearance control panel and setting the HTML template for each item in a folder to the following:
<a href="%%pathUrl%%">link</a><br> title - %% pathtitle %%<br> url - %% pathurl %%<br> icon - %% pathicon align=top %%<br> has messages - %% pathhasMessages %%<br> one message - %% pathhasoneMessage %%<br> message count - %% pathmessagecount %%<br> new messages - %% pathhasnewmessages %%<br> one new message - %% pathhasonenewmessage %%<br> new message count - %% pathnewmessagecount %%<br> created by sysop - %% pathcreatedbysysop %%<br> creator name - %% pathcreatorName %%<br> creator URL - %% pathcreatorURL %%<br> created date - %% pathcreatedDate M2D2Y2%%<br> created date default - %% pathcreatedDate %%<br> modified date - %% pathModifiedDate M2D2Y2 %%<br> modified date default - %% pathModifiedDate %%<br> path is none - %% pathisnone %%<br> is folder - %% pathisfolder %%<br> is discussion - %% pathisdiscussion %%<br> is top - %% pathistop %%<br> date - %% date M2D2Y2%%<br> date default - %% date %%<br> time - %% time H2I2 %%<br> time default - %% time %%<br> <pre> 12345%%pad 10%%xx 12345%%pad 2%%67890 12<b>34</b>5%%pad 10%%xx </pre> is unknown - %% userIsUnknown %%<br> is sysop - %% userIsSysop %%<br> is host - %% userIsHost %%<br> is guest - %% userIsGuest %%<br> is registered - %% userIsRegistered %%<br> certificate - %% certificate %%<br> creator line 2 - %% pathcreatorLine2 %%<br> site title - %% sitetitle %%<br> site URL - %% siteUrl %%<br> parent URL - %% parentUrl %%<br> back path - %% backpath %%<br> serve pictures - %% servepictures %%<br> serve info pictures - %% serveInfoPictures %%<br> version - %% version %%<br> platform - %% platform %%<br> newdiscuss - %% newdiscuss %%<br>
%% if pathIsTop %% ...your normal text, including links into the conference... %% else %% Please log in. %% endif %%
The result is that when a user logs in and they are going to the top level, they will see your normal login heading. If they follow a link from that login page, they will be going to a specific place, and will just see the "Please log in" heading.